﻿//BaseApplication.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Xaml
{
	using System;
	using System.Diagnostics;
	using System.Threading;
	using System.Windows;
	using System.Windows.Threading;

	using Ecng.Common;
	using Ecng.Reflection;
	using Ecng.Xaml;

	using StockSharp.Logging;

	/// <summary>
	/// Базовый класс для WPF приложений.
	/// </summary>
	public abstract class BaseApplication : Application
	{
		private bool _isInitialized;

		/// <summary>
		/// Инициализировать <see cref="BaseApplication"/>.
		/// </summary>
		protected BaseApplication()
		{
			ShutdownMode = ShutdownMode.OnMainWindowClose;
			DispatcherUnhandledException += OnDispatcherUnhandledException;
			System.Windows.Forms.Application.ThreadException += OnThreadException;

			ShowExceptions = true;
		}

		/// <summary>
		/// Показывать на экран ошибки, или только передавать их в <see cref="LogManager"/>. По-умолчанию ошибки показываются.
		/// </summary>
		public bool ShowExceptions { get; set; }

		private void HandleException(Exception exception, bool isWpf)
		{
			try
			{
				exception.LogError();

				if (!_isInitialized)
				{
					if (MainWindow != null)
						_isInitialized = !MainWindow.GetValue<Window, VoidType, bool>("IsSourceWindowNull", null);
				}

				if (isWpf && ShowExceptions)
				{
					var builder = new MessageBoxBuilder()
						.Caption(TypeHelper.ApplicationName)
						.Text(exception.ToString())
						.Error();

					if (_isInitialized)
						builder.Owner(MainWindow);

					builder.Show();
				}

				if (!_isInitialized)
					Shutdown();
			}
			catch (Exception e)
			{
				try
				{
					e.LogError();
				}
				catch (Exception e1)
				{
					// как последняя возможность вывести ошибки
					Trace.WriteLine(e);
					Trace.WriteLine(e1);
				}

				Shutdown(); // в процессе показа диалога с ошибкой у нас ошибка - значит все совсем плохо.
			}
		}

		private void OnThreadException(object sender, ThreadExceptionEventArgs e)
		{
			HandleException(e.Exception, false);
		}

		private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
		{
			HandleException(e.Exception, true);
			e.Handled = true;
		}
	}
}